#!/usr/bin/env node

/**
 * 电影应用部署脚本
 * 支持开发、测试、生产环境的自动化部署
 */

import { spawn } from 'child_process';
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
import { getConfig } from './deploy.config.js';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);

// 命令行参数解析
const args = process.argv.slice(2);
const environment = args[0] || 'development';
const action = args[1] || 'build';

// 颜色输出
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m',
  magenta: '\x1b[35m',
  cyan: '\x1b[36m',
};

function log(message, color = 'reset') {
  console.log(`${colors[color]}${message}${colors.reset}`);
}

function error(message) {
  log(`❌ ${message}`, 'red');
}

function success(message) {
  log(`✅ ${message}`, 'green');
}

function info(message) {
  log(`ℹ️ ${message}`, 'blue');
}

function warn(message) {
  log(`⚠️ ${message}`, 'yellow');
}

// 环境检查
function checkEnvironment() {
  const config = getConfig(environment);
  
  log(`\n🎯 开始部署 - ${config.name}`, 'magenta');
  log(`环境: ${environment}`, 'cyan');
  log(`操作: ${action}`, 'cyan');
  
  // 检查Node版本
  const nodeVersion = process.version;
  const requiredVersion = '16.0.0';
  
  if (parseFloat(nodeVersion.slice(1)) < parseFloat(requiredVersion)) {
    error(`Node.js版本过低，需要 ${requiredVersion} 或更高版本，当前版本: ${nodeVersion}`);
    process.exit(1);
  }
  
  // 检查package.json是否存在
  if (!fs.existsSync('package.json')) {
    error('package.json文件不存在，请在项目根目录运行此脚本');
    process.exit(1);
  }
  
  success('环境检查通过');
}

// 执行命令
function executeCommand(command, args, options = {}) {
  return new Promise((resolve, reject) => {
    const child = spawn(command, args, {
      stdio: 'inherit',
      shell: true,
      ...options,
    });
    
    child.on('close', (code) => {
      if (code === 0) {
        resolve();
      } else {
        reject(new Error(`命令执行失败，退出码: ${code}`));
      }
    });
    
    child.on('error', (err) => {
      reject(err);
    });
  });
}

// 安装依赖
async function installDependencies() {
  info('安装依赖...');
  
  try {
    // 检查是否有package-lock.json或yarn.lock
    const useYarn = fs.existsSync('yarn.lock');
    const command = useYarn ? 'yarn' : 'npm';
    
    await executeCommand(command, ['install']);
    success('依赖安装完成');
  } catch (err) {
    error(`依赖安装失败: ${err.message}`);
    throw err;
  }
}

// 代码检查
async function runLint() {
  info('运行代码检查...');
  
  try {
    await executeCommand('npm', ['run', 'lint']);
    success('代码检查通过');
  } catch (err) {
    warn('代码检查失败，继续构建...');
  }
}

// 类型检查
async function runTypeCheck() {
  info('运行类型检查...');
  
  try {
    await executeCommand('npm', ['run', 'type-check']);
    success('类型检查通过');
  } catch (err) {
    if (environment === 'production') {
      error('生产环境类型检查失败，停止部署');
      throw err;
    }
    warn('类型检查失败，继续构建...');
  }
}

// 构建项目
async function buildProject() {
  info('开始构建项目...');
  
  const config = getConfig(environment);
  const buildCommand = environment === 'production' ? 'build:prod' : 
                       environment === 'test' ? 'build:test' : 'build';
  
  try {
    await executeCommand('npm', ['run', buildCommand]);
    success(`项目构建完成，输出目录: ${config.outputDir}`);
  } catch (err) {
    error(`项目构建失败: ${err.message}`);
    throw err;
  }
}

// 文件大小分析
async function analyzeBundle() {
  if (environment !== 'production') return;
  
  info('分析打包文件大小...');
  
  try {
    // 动态导入ES模块
    const { analyze } = await import('vite-bundle-analyzer');
    await analyze({
      open: false,
      generateStatsFile: true,
    });
    success('打包分析完成');
  } catch (err) {
    warn(`打包分析失败: ${err.message}`);
  }
}

// 部署到服务器
async function deployToServer() {
  if (environment === 'development') {
    info('开发环境跳过部署');
    return;
  }
  
  info('开始部署到服务器...');
  const config = getConfig(environment);
  
  // 这里可以根据实际部署需求实现具体的部署逻辑
  // 例如：上传到CDN、部署到云服务器等
  
  if (environment === 'test') {
    // 测试环境部署逻辑
    log('执行测试环境部署...', 'yellow');
    // 示例：使用rsync部署到测试服务器
    // await executeCommand('rsync', [
    //   '-avz',
    //   '--delete',
    //   `${config.outputDir}/`,
    //   'user@test-server:/var/www/movie-app/'
    // ]);
  } else if (environment === 'production') {
    // 生产环境部署逻辑
    log('执行生产环境部署...', 'yellow');
    // 示例：使用Docker部署
    // await executeCommand('docker', ['build', '-t', 'movie-app', '.']);
    // await executeCommand('docker', ['push', 'movie-app']);
  }
  
  success('部署完成');
}

// 健康检查
async function healthCheck() {
  if (environment === 'development') return;
  
  info('执行健康检查...');
  
  // 这里可以实现具体的健康检查逻辑
  // 例如：检查API是否可用、页面是否能正常访问等
  
  setTimeout(() => {
    success('健康检查通过');
  }, 3000);
}

// 主部署流程
async function main() {
  try {
    // 1. 环境检查
    checkEnvironment();
    
    // 2. 安装依赖
    await installDependencies();
    
    // 3. 代码质量检查
    await runLint();
    await runTypeCheck();
    
    // 4. 构建项目
    await buildProject();
    
    // 5. 打包分析（仅生产环境）
    await analyzeBundle();
    
    // 6. 部署到服务器
    await deployToServer();
    
    // 7. 健康检查
    await healthCheck();
    
    log(`\n🎉 ${getConfig(environment).name}部署完成！`, 'green');
    log(`部署时间: ${new Date().toLocaleString()}`, 'cyan');
    
  } catch (err) {
    error(`部署失败: ${err.message}`);
    process.exit(1);
  }
}

// 使用说明
function showUsage() {
  log('\n📖 使用说明:', 'cyan');
  log('npm run deploy [environment] [action]', 'yellow');
  log('\n环境参数:', 'blue');
  log('  dev        - 开发环境');
  log('  test       - 测试环境');
  log('  prod       - 生产环境');
  log('\n操作参数:', 'blue');
  log('  build      - 仅构建（默认）');
  log('  deploy     - 构建并部署');
  log('\n示例:', 'green');
  log('  npm run deploy dev          # 开发环境构建');
  log('  npm run deploy test deploy  # 测试环境构建并部署');
  log('  npm run deploy prod deploy  # 生产环境构建并部署');
}

// 命令行参数处理
if (args.includes('--help') || args.includes('-h')) {
  showUsage();
  process.exit(0);
}

// 添加deploy脚本到package.json
function addDeployScript() {
  const packagePath = path.join(__dirname, 'package.json');
  const pkg = JSON.parse(fs.readFileSync(packagePath, 'utf8'));
  
  if (!pkg.scripts.deploy) {
    pkg.scripts.deploy = 'node deploy.js';
    fs.writeFileSync(packagePath, JSON.stringify(pkg, null, 2));
    success('已添加deploy脚本到package.json');
  }
}

// 初始化检查
if (!fs.existsSync('deploy.js')) {
  // 如果是第一次运行，添加deploy脚本
  addDeployScript();
}

// 执行主流程
main();